#include "globals.h"

/***	imports		***/
Import *addImport(char *classpath){
	char *last=strrchr(classpath, '.');
	Import *imp=NEW(Import);
	
	imp->fullname=strdup(classpath);
	
	if(last){
		imp->package=strdup(classpath);
		last=strrchr(imp->package, '.');
		last[0]=0;
		imp->class=last+1;
	}
	else {
		imp->package=strdup("");
		imp->class=strdup(classpath);
	}
	
	imp->next=0;
	return imp;	
}

Import *addLastImport(char *cp){
	Import *imp=program->imports;
	if(imp==0) {
		program->imports=addImport(cp);
		return imp;
	} 
	
	for(;imp->next;imp=imp->next);
	imp->next=addImport(cp);
	return imp;		
}

Import *getImport(char *class){
	Import *imp;
	for(imp=program->imports;imp;imp=imp->next){
		if(strcmp(imp->fullname, class)==0) return imp;
		if(strcmp(imp->class, class)==0) return imp;
	}
	return 0;	
}

Import *setLastImport(Import *parent, Import *imp){
	if(parent==0) return imp;
	Import *m;
	for(m=parent;m->next;m=m->next);
	m->next=imp;
	return m;
}

/***	variables	***/
Variable *addVariable(char *type, char *name){
//	printf("addVar: %s of type %s\n", name, type);
	Variable *var=NEW(Variable);
	var->name=strdup(name);
	var->type=strdup(type);
	if(translateType(type)[0]=='C') var->isObject=1;
	else var->isObject=0;
	var->next=0;
	return var;	
}

Variable *setLastVariable(Variable *parent, Variable *var){
	if(parent==0) return var;
	Variable *v;
	for(v=parent;v->next;v=v->next);
	v->next=var;
//	printf("setLast: '%s' => '%s'\n", v->name, var->name);
	return parent;
}

char *getType(char *typename){
	Import *imp=getImport(typename);
	if(imp)
		return strdup(imp->fullname);	
	else
		return strdup(typename);
}

Variable *getVariable(char *name, Variable *root){
	Variable *v;
	for(v=root;v;v=v->next)
		if(strcmp(v->name, name)==0) return v;
	return 0;	
}

int isSetVariable(char *name, Variable *root) {
	Variable *v;
	for(v=root;v;v=v->next)
		if(strcmp(v->name, name)==0) {
			if(v->isObject)	return -1;
			else return 1;
		}
	return 0;
}

/***	methods		***/
Method *addMethod(char *type, char *name, Variable *args, void *code){
	Method *m=NEW(Method);	
	m->type=strdup(type);
	m->name=strdup(name);
	m->args=args;
	m->code=code;
	m->argshs=hashArguments(args);
	m->next=0;
	return m;
}


Method *addConstructor(char *name, Variable *args, void *code){
	Method *m=NEW(Method);	
	m->type=strdup("null");
	m->name=strdup(name);
	m->args=args;
	m->code=code;
	m->argshs=hashArguments(args);
	m->next=0;
	return m;
}

Method *getMethod(Method *parent, char *name, char *hash){
	Method *m;
	for(m=parent;m;m=m->next)
		if((strcmp(m->name, name)==0) && (strcmp(m->argshs, hash)==0)) return m;
	
	return 0;			
}

Method *setLastMethod(Method *parent, Method *met){
	if(parent==0) return met;
	Method *m;
	for(m=parent;m->next;m=m->next);
	m->next=met;
	return parent;
}

/***	elements	***/
BaseElement *addBaseElement(elementType type, void *content){
	BaseElement *el=NEW(BaseElement);
	el->type=type;
	el->content=content;
	el->next=0;
	return el;
}

Element *setLastElement(Element *parent, Element *el){
	if(parent==0) return el;
	Element *m;
	for(m=parent;m->next;m=m->next);
	m->next=el;
	return parent;
}

Expression *addExpression(Expression *left, Expression *right, int operator){	
	Expression *exp=NEW(Expression);
	exp->type=EXP;
	exp->next=0;
	exp->left=(void*)left;
	exp->right=(void*)right;
	exp->operator=operator;
	return exp;
}

